package cn.mujiankeji.mbrowser.功能.播放框.模型

import android.annotation.SuppressLint
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import android.app.Activity
import android.content.Context
import android.media.AudioManager
import android.provider.Settings
import android.view.View
import androidx.compose.runtime.mutableStateListOf
import cn.mujiankeji.mbrowser.功能.播放框.核心.ExoPlayer
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.BarUtils
import com.blankj.utilcode.util.VolumeUtils
import android.content.pm.ActivityInfo
import cn.mujiankeji.mbrowser.工具.mlog
import androidx.media3.common.C
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch


@SuppressLint("UnsafeOptInUsageError")
class 播放框视图状态<T>(
    var context : Context,
    var player : ExoPlayer = ExoPlayer(context),
    val 播放源 : 播放内容来源<T>,
    val 更新视频倍速 : (Float) -> Unit,
    val 界面状态改变 : (全屏 : Boolean,画中画 : Boolean) -> Unit,
    val 准备就绪 : ()->Unit,
    )
{
    var coroutine : CoroutineScope ?= null
    var 显示设置 by mutableStateOf(false)
    var 显示选集 by mutableStateOf(false)
    var 显示导航栏 by mutableStateOf(false)
    var 画面布局样式 by mutableStateOf(播放框画面布局枚举.默认)
    var 画中画模式 by mutableStateOf(false)
    var 全屏模式 by mutableStateOf(false)
    
    // 长按倍速相关状态
    var 长按倍速中 by mutableStateOf(false)
    var 长按倍速值 = 3.0f  // 长按倍速默认值
    var 长按前倍速 = 1.0f  // 存储长按前的倍速值

    // 手势状态
    val 手势状态 = 播放框手势状态()

    // 亮度控制
    val 亮度控制器 = 亮度控制(context)

    // 导航栏自动隐藏延迟（毫秒）
    val 导航栏自动隐藏延迟 = 3000L

    // 播放信息
    var 含下一集 by mutableStateOf(false)
    var 当前播放列表 by mutableStateOf<List<T>?>(null)
    var 当前播放项目 by mutableStateOf<T?>(null)
    var 当前播放的源分类名称 by mutableStateOf<String?>(null)
        private set

    suspend fun 设置播放项目(源分类 : String,项目 : T){
        当前播放的源分类名称 = 源分类
        当前播放项目 = 项目
        当前播放列表 = 播放源.取列表(源分类)
        含下一集 = 当前播放项目 != 当前播放列表?.last()
        player.停止()

        当前项目加载信息.clear()
        播放源.取播放文件(项目,{
            当前项目加载信息.add(it)
        }).let {
            player.播放(it)
        }
        当前项目加载信息.clear()
    }
    var 当前项目加载信息 = mutableStateListOf<String>()




    init {
        // 初始化音量
        手势状态.当前音量 = player.是否静音.value.let { if (it) 0f else 1f }

        // 尝试初始化亮度
        try {
            val 当前亮度 = 亮度控制器.获取窗口亮度(ActivityUtils.getTopActivity())
            if (当前亮度 >= 0) {
                手势状态.当前亮度 = 当前亮度
            } else {
                // 如果窗口亮度未设置（值为负数），则使用系统亮度
                手势状态.当前亮度 = 亮度控制器.系统亮度转比例(亮度控制器.获取系统亮度())
            }
        } catch (e: Exception) {
            // 出错时使用默认值
            手势状态.当前亮度 = 0.5f
        }
    }

    // 显示导航栏并设置自动隐藏
    fun 显示导航栏并自动隐藏() {
        显示导航栏 = true
        手势状态.导航栏计时器 = System.currentTimeMillis() + 导航栏自动隐藏延迟
    }

    // 检查是否应该隐藏导航栏
    fun 检查导航栏显示状态() {
        if (显示导航栏 && System.currentTimeMillis() > 手势状态.导航栏计时器) {
            显示导航栏 = false
        }
    }

    fun 切换至画中画(){
        画中画模式 = true
        界面状态改变(全屏模式,画中画模式)
    }
    fun 取消画中画(){
        画中画模式 = false
        界面状态改变(全屏模式,画中画模式)
    }

    fun 翻转屏幕方向(){
        val activity = ActivityUtils.getTopActivity()
        val currentOrientation = activity.resources.configuration.orientation
        if (currentOrientation == android.content.res.Configuration.ORIENTATION_LANDSCAPE) {
            activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        } else {
            activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
        }
    }
    fun 切换至全屏(){
        全屏模式 = true
        val activity = ActivityUtils.getTopActivity()
        BarUtils.setStatusBarVisibility(activity, false)
        BarUtils.setNavBarVisibility(activity, false)
        activity.window.decorView.systemUiVisibility =
            (View.SYSTEM_UI_FLAG_FULLSCREEN
                    or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)

        // 切换至全屏时，应当判断视频的长宽，若是长视频应当默认横屏，否则纵屏
        val 视频信息 = player.视频信息.value
        if (视频信息 != null && 视频信息.宽度 > 0 && 视频信息.高度 > 0) {
            if (视频信息.宽度 >= 视频信息.高度) {
                activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
            } else {
                activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
            }
        }
        界面状态改变(全屏模式,画中画模式)
    }

    fun 取消全屏(){
        mlog("取消全屏")
        全屏模式 = false
        val activity = ActivityUtils.getTopActivity()
        BarUtils.setStatusBarVisibility(activity, true)
        BarUtils.setNavBarVisibility(activity, true)
        activity.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE

        // 全屏全屏时需确保自动跳转为系统默认的屏幕方向
        activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
        界面状态改变(全屏模式,画中画模式)
    }

    var 锁屏状态 by mutableStateOf(false)
    fun 切换锁屏状态(){
        锁屏状态 = !锁屏状态
    }

    fun 切换画面布局样式(布局 : 播放框画面布局枚举){
        画面布局样式 = 布局
        // todo 可通过事件/回调通知 UI 更新布局
    }

    /**
     * 按下播放或暂停按钮
     */
    fun 切换播放状态(){
        if (player.播放状态.value == 播放状态枚举.播放中) {
            player.暂停()
        } else {
            player.播放()
        }
    }

    fun 下一集(){
        coroutine?.launch {
            val index = 当前播放列表?.indexOf(当前播放项目)
            index?.let {
                if (当前播放列表!!.size - 1 > index){
                    设置播放项目(当前播放的源分类名称!!,当前播放列表!![index+1])
                }
            }
        }

    }

    /**
     * 调整亮度
     * @param 变化值 亮度变化值，范围 -1.0f ~ 1.0f
     */
    fun 调整亮度(变化值: Float) {
        // 平滑地更新亮度值，确保在0.01-1.0范围内
        val 新亮度 = (手势状态.当前亮度 + 变化值).coerceIn(0.01f, 1.0f)
        
        // 只有当亮度实际变化时才设置，避免频繁设置相同值
        if (kotlin.math.abs(新亮度 - 手势状态.当前亮度) > 0.01f) {
            手势状态.当前亮度 = 新亮度
            
            // 实际应用亮度变化
            try {
                亮度控制器.设置窗口亮度(ActivityUtils.getTopActivity(), 手势状态.当前亮度)
            } catch (e: Exception) {
                // 忽略权限错误
            }
        }
        
        手势状态.显示亮度调节 = true
        手势状态.亮度调节计时器 = System.currentTimeMillis() + 1500
    }

    /**
     * 调整音量
     * @param 变化值 音量变化值，范围 -1.0f ~ 1.0f
     */
    fun 调整音量(变化值: Float) {
        val max = VolumeUtils.getMaxVolume(AudioManager.STREAM_MUSIC)
        val current = VolumeUtils.getVolume(AudioManager.STREAM_MUSIC)
        val delta = (max * 变化值).toInt()
        val newVolume = (current + delta).coerceIn(0, max)
        VolumeUtils.setVolume(AudioManager.STREAM_MUSIC, newVolume, 0)
        // UI反馈
        手势状态.当前音量 = newVolume.toFloat() / max
        手势状态.显示音量调节 = true
        手势状态.音量调节计时器 = System.currentTimeMillis() + 1500
    }

    /**
     * 调整进度
     * @param 目标百分比 目标进度百分比，范围 0.0f ~ 1.0f
     */
    fun 调整进度(目标百分比: Float) {
        手势状态.目标进度百分比 = 目标百分比.coerceIn(0.0f, 1.0f)
        手势状态.显示进度调节 = true
        手势状态.进度调节计时器 = System.currentTimeMillis() + 1500
    }

    /**
     * 应用进度调整
     */
    fun 应用进度调整() {
        if (手势状态.显示进度调节) {
            val 总时长 = player.总时长.value
            if (总时长 > 0) {
                val 目标位置 = (总时长 * 手势状态.目标进度百分比).toLong()
                player.跳转(目标位置)
            }
            手势状态.显示进度调节 = false
        }
    }

    /**
     * 检查并更新手势状态显示
     */
    fun 检查手势状态显示() {
        val 当前时间 = System.currentTimeMillis()

        if (手势状态.显示亮度调节 && 当前时间 > 手势状态.亮度调节计时器) {
            手势状态.显示亮度调节 = false
        }

        if (手势状态.显示音量调节 && 当前时间 > 手势状态.音量调节计时器) {
            手势状态.显示音量调节 = false
        }

        if (手势状态.显示进度调节 && 当前时间 > 手势状态.进度调节计时器) {
            手势状态.显示进度调节 = false
        }
    }


    fun 是否为直播() : Boolean{
        val exo = player.播放器
        return exo?.isCurrentWindowLive == true ||
                exo?.duration == C.TIME_UNSET
    }

    /**
     * 开始长按倍速播放
     * 将当前播放速率临时提高到预设值(默认3.0倍速)
     */
    fun 开始长按倍速() {
        if (!长按倍速中){
            长按前倍速 = player.播放速率.value  // 保存当前倍速
            长按倍速中 = true
            player.设置播放速率(长按倍速值)
        }

    }
    
    /**
     * 结束长按倍速播放
     * 恢复到长按前的播放速率
     */
    fun 结束长按倍速() {
        if (长按倍速中) {
            player.设置播放速率(长按前倍速)
        }
        长按倍速中 = false
    }

}

/**
 * 播放框手势状态
 */
class 播放框手势状态 {
    // 亮度调节
    var 当前亮度 by mutableStateOf(0.5f) // 0.0f ~ 1.0f
    var 显示亮度调节 by mutableStateOf(false)
    var 亮度调节计时器 = 0L
    
    // 音量调节
    var 当前音量 by mutableStateOf(0.5f) // 0.0f ~ 1.0f
    var 显示音量调节 by mutableStateOf(false)
    var 音量调节计时器 = 0L
    
    // 进度调节
    var 当前进度百分比 by mutableStateOf(0f) // 0.0f ~ 1.0f
    var 目标进度百分比 by mutableStateOf(0f) // 拖动后的目标进度
    var 显示进度调节 by mutableStateOf(false)
    var 进度调节计时器 = 0L
    
    // 导航栏显示控制
    var 导航栏计时器 = 0L
    
    // 手势类型
    enum class 手势类型 {
        无,
        亮度,
        音量,
        进度
    }
    
    var 当前手势 by mutableStateOf(手势类型.无)
    
    // 重置所有显示状态
    fun 重置显示状态() {
        显示亮度调节 = false
        显示音量调节 = false
        显示进度调节 = false
        当前手势 = 手势类型.无
    }
}

/**
 * 亮度控制工具类
 */
class 亮度控制(private val context: Context) {
    
    /**
     * 获取系统亮度模式
     * @return 是否为自动亮度模式
     */
    fun 是否自动亮度(): Boolean {
        return try {
            Settings.System.getInt(
                context.contentResolver,
                Settings.System.SCREEN_BRIGHTNESS_MODE
            ) == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
        } catch (e: Exception) {
            false
        }
    }
    
    /**
     * 获取系统亮度值（0-255）
     */
    fun 获取系统亮度(): Int {
        return try {
            Settings.System.getInt(
                context.contentResolver,
                Settings.System.SCREEN_BRIGHTNESS
            )
        } catch (e: Exception) {
            128
        }
    }
    
    /**
     * 获取当前窗口亮度（0.0-1.0）
     */
    fun 获取窗口亮度(activity: Activity): Float {
        val lp = activity.window.attributes
        return lp.screenBrightness
    }
    
    /**
     * 设置当前窗口亮度（0.0-1.0）
     */
    fun 设置窗口亮度(activity: Activity, 亮度: Float) {
        val lp = activity.window.attributes
        lp.screenBrightness = 亮度.coerceIn(0.01f, 1.0f)  // 避免设置为0导致系统使用默认亮度
        activity.window.attributes = lp
    }
    
    /**
     * 将系统亮度值（0-255）转换为比例值（0.0-1.0）
     */
    fun 系统亮度转比例(亮度: Int): Float {
        return 亮度 / 255f
    }
    
    /**
     * 将比例值（0.0-1.0）转换为系统亮度值（0-255）
     */
    fun 比例转系统亮度(比例: Float): Int {
        return (比例 * 255).toInt()
    }
} 